package com.sql.blood.common.util;

import com.sql.blood.common.model.TabLine;
import org.neo4j.driver.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GraphDatabaseConnection {

    private final static Logger logger = LoggerFactory.getLogger(GraphDatabaseConnection.class);
    private final Driver driver;

    public GraphDatabaseConnection() {
        String uri = "bolt://10.197.236.211:7687";
        driver = GraphDatabase.driver(uri, AuthTokens.basic("neo4j", "123456"));
    }

    public void insertVertex(TabLine tabLine) {
        Session session = driver.session();
        try {
            Transaction tx = session.beginTransaction();
            String exist = String.format("MATCH (a:Table) WHERE\n" +
                    "a.url = '%s'and\n" +
                    "a.datasource = '%s'and\n" +
                    "a.database = '%s'and\n" +
                    "a.name = '%s'\n" +
                    "RETURN a", tabLine.getUrl(), tabLine.getDatasource(), tabLine.getDatabase(), tabLine.getTable());
            Result res = tx.run(exist);
            if (!res.hasNext()) {
                tx.run(String.format("CREATE (a:Table {\n" +
                        "url: '%s',\n" +
                        "datasource: '%s',\n" +
                        "database: '%s',\n" +
                        "name: '%s'\n" +
                        "})", tabLine.getUrl(), tabLine.getDatasource(), tabLine.getDatabase(), tabLine.getTable()));
            }
            tx.commit();
            tx.close();
        } finally {
            session.close();
        }
    }

    public void insertEdge(TabLine origin, TabLine dest) {
        Session session = driver.session();
        try {
            Transaction tx = session.beginTransaction();
            String exist = String.format("MATCH (a:Table)-[r:TableBlood]->(b:Table) WHERE\n" +
                            "a.url = '%s' AND b.url = '%s' and\n" +
                            "a.name = '%s' AND b.name = '%s' and\n" +
                            "a.datasource = '%s' AND b.datasource = '%s' and\n" +
                            "a.database = '%s' AND b.database = '%s'\n" +
                            "RETURN r",
                    origin.getUrl(), dest.getUrl(),
                    origin.getTable(), dest.getTable(),
                    origin.getDatasource(), dest.getDatasource(),
                    origin.getDatabase(), dest.getDatabase());
            Result res = tx.run(exist);
            if (!res.hasNext()) {
                tx.run(String.format("MATCH (a:Table),(b:Table) WHERE\n" +
                                "a.url = '%s' AND b.url = '%s' and\n" +
                                "a.name = '%s' AND b.name = '%s' and\n" +
                                "a.datasource = '%s' and b.datasource = '%s' and\n" +
                                "a.database = '%s' and b.database = '%s'\n" +
                                "CREATE (a)-[r:TableBlood]->(b)",
                        origin.getUrl(), dest.getUrl(),
                        origin.getTable(), dest.getTable(),
                        origin.getDatasource(), dest.getDatasource(),
                        origin.getDatabase(), dest.getDatabase()));
            }
            tx.commit();
            tx.close();
        } finally {
            session.close();
        }
    }

    public void close() {
        driver.close();
        logger.info("close neo4j connection ...");
    }
}
